package com.hawk.android.phonecontrller;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.text.Layout;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.Spinner;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;

public class JoyStick extends Activity implements SensorEventListener {

	private BluetoothAdapter mBluetoothAdapter = null;
	private static final int REQUEST_CONNECT_DEVICE = 1;
	public static final int MESSAGE_STATE_CHANGE = 1;
	public static final int MESSAGE_READ = 2;
	public static final int MESSAGE_WRITE = 3;
	public static final int MESSAGE_DEVICE_NAME = 4;
	public static final int MESSAGE_TOAST = 5;
	private static final int REQUEST_ENABLE_BT = 2;
	public static final String DEVICE_NAME = "device_name";
	public static final String TOAST = "toast";
	private BluetoothChatService mChatService;
	private TextView mTitle;
	
	private char[][] key=new char[][]{
			{' ','E','1','2','3','4','5','6','7','8','9','0'},
			{'B','\'','q','w','e','r','t','y','u','i','o','p'},
			{'C','/','a','s','d','f','g','h','j','k','l',';'},
			{'S','T','z','x','c','v','b','n','m',',','.'},
			{'R','A','-','=','[',']','\\','`'}};
	private String[][] keyName=new String[][]{
			{"Space","Enter","1","2","3","4","5","6","7","8","9","0"},
			{"BackSpace","\'","q","w","e","r","t","y","u","i","o","p"},
			{"CapsLk","/","a","s","d","f","g","h","j","k","l",";"},
			{"Shift","Tab","z","x","c","v","b","n","m",",","."},
			{"Ctrl","Alt","-","=","[","]","\\","`"}
	};

	private SensorManager mSensorManager;
	private PowerManager mPowerManager;
	private WindowManager mWindowManager;
	private Display mDisplay;
	private WakeLock mWakeLock;

	private Sensor mAccelerometer;

	private float mSensorX;
	private float mSensorY;

	private boolean stopped = true;

	private JoyStick tmpThis;
	
	private float baseX,baseY;
	private boolean baseSwitch=true;
	
	private View ChildBoardLayout=null;
	private LinearLayout mainLayout=null;
	
	private LinearLayout InitialLayout()
	{
		LinearLayout llayout=new LinearLayout(this);
		llayout.setOrientation(LinearLayout.VERTICAL);
		LinearLayout.LayoutParams Lableparams=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT,1);
	
		LinearLayout.LayoutParams changeableParams=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT, 0.2f);
		TableLayout tbLayout=new TableLayout(this);
		Spinner spinner=new Spinner(this);
		llayout.addView(spinner,Lableparams);
		llayout.addView(tbLayout,changeableParams);
		ChildBoardLayout=tbLayout;
		
		
		return llayout;
	}
	private void setKeyBoardStyle()
	{
		mainLayout.removeView(ChildBoardLayout);
		LinearLayout.LayoutParams changeableParams=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT, 0.2f);
		TableLayout tblLayout=new TableLayout(this);
		mainLayout.addView(tblLayout, changeableParams);
		for (int i=0;i<5;i++)
		{
			TableRow tmpRow=new TableRow(this);
			tblLayout.addView(tmpRow);
			for (int j=0;j<key[i].length;j++)
			{
				Button TmpBtn=new Button(this);
				final String test=keyName[i][j]; 
				TmpBtn.setText(keyName[i][j]);
				TmpBtn.setOnTouchListener(new OnTouchListener() {
					
					@Override
					public boolean onTouch(View v, MotionEvent event) {
						// TODO Auto-generated method stub
						switch (event.getAction()) {
						case MotionEvent.ACTION_UP:
							Log.d("KeyUp", test);
							break;

						case MotionEvent.ACTION_DOWN:
							Log.d("KeyDown", test);
							break;
						default:
							break;
						}
						return false;
					}
				});
				tmpRow.addView(TmpBtn);
			}
		}
		setContentView(mainLayout);
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

		tmpThis = this;

		// Get an instance of the SensorManager
		mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

		// Get an instance of the PowerManager
		mPowerManager = (PowerManager) getSystemService(POWER_SERVICE);

		// Get an instance of the WindowManager
		mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
		mDisplay = mWindowManager.getDefaultDisplay();

		// Create a bright wake lock
		mWakeLock = mPowerManager.newWakeLock(
				PowerManager.SCREEN_BRIGHT_WAKE_LOCK, getClass().getName());

		// instantiate our simulation view and set it as the activity's content
		mAccelerometer = mSensorManager
				.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

		DisplayMetrics metrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(metrics);

		setContentView(mainLayout=InitialLayout());
		setKeyBoardStyle();
//		setContentView(R.layout.activity_joystick);
		setTitle("JoyStick Simulator");

		getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
				R.layout.custom_title);

		// Set up the custom title
		mTitle = (TextView) findViewById(R.id.title_left_text);
		mTitle.setText(R.string.app_name);
		mTitle = (TextView) findViewById(R.id.title_right_text);

		mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
		if (mBluetoothAdapter == null) {
			Toast.makeText(this, "Bluetooth is not available",
					Toast.LENGTH_LONG).show();
			finish();
			return;
		}

		Log.v("gdbinfo", "onCreate() finished");

	}
	void CtrlSwitcher()
	{
		if (!stopped) {
			stopped = true;
			mSensorManager.unregisterListener(tmpThis);
		} else if (stopped) {
			stopped = false;
			mSensorManager.registerListener(tmpThis, mAccelerometer,
					SensorManager.SENSOR_DELAY_UI);

		}
	}

	private final Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case MESSAGE_STATE_CHANGE:
				switch (msg.arg1) {
				case BluetoothChatService.STATE_CONNECTED:
					mTitle.setText(R.string.title_connected_to);
					break;
				case BluetoothChatService.STATE_CONNECTING:
					mTitle.setText(R.string.title_connecting);
					break;
				case BluetoothChatService.STATE_LISTEN:
				case BluetoothChatService.STATE_NONE:
					mTitle.setText(R.string.title_not_connected);
					break;
				}
				break;
			case MESSAGE_WRITE:
				byte[] writeBuf = (byte[]) msg.obj;
				// construct a string from the buffer
				String writeMessage = new String(writeBuf);
				break;
			case MESSAGE_READ:
				byte[] readBuf = (byte[]) msg.obj;
				// construct a string from the valid bytes in the buffer
				String readMessage = new String(readBuf, 0, msg.arg1);
				break;
			case MESSAGE_DEVICE_NAME:
				// save the connected device's name
				String mConnectedDeviceName = msg.getData().getString(
						DEVICE_NAME);
				Toast.makeText(getApplicationContext(),
						"Connected to " + mConnectedDeviceName,
						Toast.LENGTH_SHORT).show();
				break;
			case MESSAGE_TOAST:
				Toast.makeText(getApplicationContext(),
						msg.getData().getString(TOAST), Toast.LENGTH_SHORT)
						.show();
				break;
			}
		}
	};

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		switch (requestCode) {
		case REQUEST_CONNECT_DEVICE:
			if (resultCode == Activity.RESULT_OK) {
				String address = data.getExtras().getString(
						DeviceListActivity.EXTRA_DEVICE_ADDRESS);
				BluetoothDevice device = mBluetoothAdapter
						.getRemoteDevice(address);
				mChatService.connect(device);
			}
		}
	}

	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		super.onStart();
		if (!mBluetoothAdapter.isEnabled()) {
			Intent enableIntent = new Intent(
					BluetoothAdapter.ACTION_REQUEST_ENABLE);
			startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
			// Otherwise, setup the chat session
		} else {
			if (mChatService == null)
				setupChat();
		}
		Log.v("gdbinfo", "onStart() finished");
	}

	private void setupChat() {

		// Initialize the BluetoothChatService to perform bluetooth connections
		mChatService = new BluetoothChatService(this, mHandler);

	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		// Stop the Bluetooth chat services
		if (mChatService != null)
			mChatService.stop();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_joystick, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		switch (item.getItemId()) {
		case R.id.Selector1:
			Intent BluetoothIntent = new Intent(this, DeviceListActivity.class);
			startActivityForResult(BluetoothIntent, REQUEST_CONNECT_DEVICE);
			return true;
		case R.id.Selector2:
			return true;
		case R.id.Selector3:
			CtrlSwitcher();
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	protected void onResume() {
		super.onResume();
		/*
		 * when the activity is resumed, we acquire a wake-lock so that the
		 * screen stays on, since the user will likely not be fiddling with the
		 * screen or buttons.
		 */
		mWakeLock.acquire();

		// Start the simulation
		if (!stopped)
			mSensorManager.registerListener(this, mAccelerometer,
					SensorManager.SENSOR_DELAY_UI);
		baseSwitch=true;
		
		Log.v("gdbinfo", "onResume() finished");
	}

	@Override
	protected void onPause() {
		super.onPause();
		/*
		 * When the activity is paused, we make sure to stop the simulation,
		 * release our sensor resources and wake locks
		 */

		mSensorManager.unregisterListener(this);
		mWakeLock.release();
	}

	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		// TODO Auto-generated method stub

	}

	public void onSensorChanged(SensorEvent event) {
		// TODO Auto-generated method stub
		if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
			return;

		switch (mDisplay.getRotation()) {
		case Surface.ROTATION_0:
			mSensorX = event.values[0];
			mSensorY = event.values[1];
			break;
		case Surface.ROTATION_90:
			mSensorX = -event.values[1];
			mSensorY = event.values[0];
			break;
		case Surface.ROTATION_180:
			mSensorX = -event.values[0];
			mSensorY = -event.values[1];
			break;
		case Surface.ROTATION_270:
			mSensorX = event.values[1];
			mSensorY = -event.values[0];
			break;
		}
		if (baseSwitch)
		{
			baseSwitch=false;
			baseX=mSensorX;
			baseY=mSensorY;
		}
		mSensorX-=baseX;
		mSensorY-=baseY;
		Log.v("PosX", String.valueOf(mSensorX));
		Log.v("PosY", String.valueOf(mSensorY));
		sendMessage(mSensorX,mSensorY);
	}

	private void sendMessage(float ax, float ay) {
		// Check that we're actually connected before trying anything
		if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
			Log.v("gdbinfo", "bluetooth not connected");
			return;
		}

		String message = "";
		if (Math.abs(ax) > 1.5) {
			if (ax > 0)
				message += 'l';
			else if (ax < 0)
				message += 'r';
		}

		if (Math.abs(ay) > 1.5) {
			if (ay > 0)
				message += 'b';
			else
				message += 'f';
		}

		// Get the message bytes and tell the BluetoothChatService to write
		byte[] send = message.getBytes();
		mChatService.write(send);

		// Reset out string buffer to zero and clear the edit text field
	}

}
